<?php
namespace App\Http\Common;
use DateInterval;
use DatePeriod;
use DateTime;
use Exception;

/**
 * 必须使用单例模式来进行创建
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019-08-14
 * Time: 21:35
 */
class DayTimes{
    //创建静态私有的变量保存该类对象
    private static $instance;
    //参数
    private $config;
    //防止直接创建对象
    private function __construct($config){
        $this->config = $config;
    }
    //防止克隆对象
    private function __clone(){
    }
    // 使用单列模式
    public static function getInstance($config=null){
        //判断$instance是否是Uni的对象
        //没有则创建
        if (!self::$instance instanceof self) {
            self::$instance = new self($config);
        }
        return self::$instance;
    }
    //现在的时间
    public function now(){
        return date("Y-m-d H:i:s",time());
    }
    //现在的时间
    public function today(){
        return date("Y-m-d",time());
    }
    //$time 的日期 时间
    public function getDate($time){
        return date("Y-m-d",''.$time);
    }
    //$time 的日期 时间 得到月份
    public function getMonth($time){
        return date("m",''.$time);
    }
    //$time 的日期 时间 得到年份月份
    public function getYearMonth($time){
        return date("Y-m",''.$time);
    }

    /**
     * 判断时间戳是否为今天
     * @param $time
     * @return bool
     */
    public function isToday($time){
        $ystd = strtotime(date("Y-m-d"));
        $ystd = date("Y-m-d",$ystd);
        $ystd = strtotime($ystd."00:00:00");
        $today = strtotime('+1 day');
        $today = date("Y-m-d",$today);
        $today = strtotime($today."00:00:00");
        if($ystd < $time && $time< $today){
            return true;
        }else{
            return false;
        }
    }
    /**
     * 计算两个日期之间相隔的天数
     * @param $a a-b
     * @param $b
     * @return float
     */
    public function countDays($a,$b){
        $a_dt = getdate($a);
        $b_dt = getdate($b);
        $a_new = mktime(12, 0, 0, $a_dt['mon'], $a_dt['mday'], $a_dt['year']);
        $b_new = mktime(12, 0, 0, $b_dt['mon'], $b_dt['mday'], $b_dt['year']);
        return round(($a_new-$b_new)/86400);
    }
    /**
     * @author injection(injection.mail@gmail.com)
     * @var date1日期1
     * @var date2 日期2
     * @var tags 年月日之间的分隔符标记,默认为'-'
     * @return 相差的月份数量
     * @example:
    $date1 = "2003-08-11";
    $date2 = "2008-11-06";
    $monthNum = getMonthNum( $date1 , $date2 );
    echo $monthNum;
     */
    function countMonths( $date1, $date2, $tags='-' ){
        $date1 = explode($tags,$date1);
        $date2 = explode($tags,$date2);
        return abs($date1[0] - $date2[0]) * 12 + abs($date1[1] - $date2[1]);
    }

    /**
     * 得到两个日期之间的所有月份
     * @param $start_time
     * @param $end_time
     * @param array $dateArr
     * @return array
     * @throws Exception
     */
    public function getAllMonths($start_time, $end_time,$dateArr=['年','月']){
        $res = [];
        $start    = new DateTime($start_time);
        $end      = new DateTime($end_time);
        // 时间间距 这里设置的是一个月
        $interval = DateInterval::createFromDateString('1 month');
        $period   = new DatePeriod($start, $interval, $end);
        foreach ($period as $dt) {
            $res[] = $dt->format("Y$dateArr[0]m$dateArr[1]") ;
        }
        return $res;
    }
    /**
     * 计算两个日期之间相隔的天数
     * @param $a
     * @param $b
     * @return float
     */
    public function countDaysAbs($a,$b){
        $a_dt = getdate($a);
        $b_dt = getdate($b);
        $a_new = mktime(12, 0, 0, $a_dt['mon'], $a_dt['mday'], $a_dt['year']);
        $b_new = mktime(12, 0, 0, $b_dt['mon'], $b_dt['mday'], $b_dt['year']);
        return round(abs($a_new-$b_new)/86400);
    }
    //拿到几天前 几天后
    public function getDayAgo($day=-7,$time = null){
        if (!$time) $time = strtotime(now());
        return date("Y-m-d H:i:s",strtotime($day." day",$time)) ;
    }
    //拿到几天前 几天后
    public function getDayAgoFormat($day=-7,$time = null){
        if (!$time) $time = strtotime(now());
        return date("Y-m-d",strtotime($day." day",$time)) ;
    }
    //拿到几月前 几月后
    public function getMonthAgo($month=-1,$time = null){
        if (!$time) $time = strtotime(now());
        return date("Y-m-d H:i:s",strtotime($month." month",$time)) ;
    }
    //拿到几月前 几月后
    public function getMonthAgoFormat($month=-1,$time = null,$dateArr=['年','月']){
        if (!$time) $time = strtotime(now());
        return date("Y$dateArr[0]m$dateArr[1]",strtotime($month." month",$time)) ;
    }
    //今天开始时间
    public function beginToday(){
        return date("Y-m-d H:i:s",mktime(0,0,0,date('m'),date('d'),date('Y')));
    }
    //今天结束时间
    public function endToday(){
        return date("Y-m-d H:i:s",mktime(0,0,0,date('m'),date('d')+1,date('Y'))-1);
    }
    //今天结束时间
    public function beginYesterday(){
        return date("Y-m-d H:i:s",mktime(0,0,0,date('m'),date('d')-1,date('Y')));
    }
    //昨天结束时间
    public function endYesterday(){
        return date("Y-m-d H:i:s",mktime(0,0,0,date('m'),date('d')-1,date('Y')));
    }
    //本周开始时间
    public function beginThisweek(){
        return date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-date("w")+1,date("Y")));
    }
    //周开始时间 $number ==1 为下一周 $number == -1 为上一周
    public function week($number){
        return date("Y-m-d",mktime(0, 0 , 0,date("m"),date("d")-date("w")+1+$number*7,date("Y")));
    }
    //本周结束时间
    public function endThisweek(){
        return date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y")));
    }
    //上周开始时间
    public function beginLastweek(){
        return date("Y-m-d H:i:s",mktime(0,0,0,date('m'),date('d')-date('w')+1-7,date('Y')));
    }
    //上周结束时间
    public function endLastweek(){
        return date("Y-m-d H:i:s",mktime(23,59,59,date('m'),date('d')-date('w')+7-7,date('Y')));
    }
    //本月开始时间
    public function beginThismonth(){
        return date("Y-m-d H:i:s",mktime(0,0,0,date('m'),1,date('Y')));
    }
    //本月结束时间
    public function endThismonth(){
        return date("Y-m-d H:i:s",mktime(23,59,59,date('m'),date('t'),date('Y')));
    }
    //月开始时间
    public function beginMonth($time){
        return date("Y-m-d H:i:s",mktime(0,0,0,date('m',$time),1,date('Y',$time)));
    }
    //月结束时间
    public function endMonth($time){
        return date("Y-m-d H:i:s",mktime(23,59,59,date('m',$time),date('t',$time),date('Y',$time)));
    }
    //上月开始时间
    public function beginLastmonth(){
        return date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m")-1,1,date("Y")));
    }
    public function endLastmonth(){
        //上月结束时间
        return date("Y-m-d H:i:s",mktime(23,59,59,date("m") ,0,date("Y")));
    }
    //本季度开始时间
    public function season(){
        return ceil((date('n'))/3);
    }
    //本季度开始时间
    public function beginThisseason(){
        return date('Y-m-d H:i:s', mktime(0, 0, 0,season*3-3+1,1,date('Y')));
    }
    //本季度结束时间
    public function endThisseason(){
        return date('Y-m-d H:i:s', mktime(23,59,59,season*3,date('t',mktime(0, 0 , 0,season*3,1,date("Y"))),date('Y')));
    }
    //上季度开始时间
     public function season1(){
        return ceil((date('n'))/3)-1;//上季度是第几季度
    }
    //上季度开始时间
    public function beginLastseason(){
        return date('Y-m-d H:i:s', mktime(0, 0, 0,season1*3-3+1,1,date('Y')));
    }
    //上季度结束时间
    public function endLastseason(){
        return date('Y-m-d H:i:s', mktime(23,59,59,season1*3,date('t',mktime(0, 0 , 0,season1*3,1,date("Y"))),date('Y')));
    }
    //本年开始时间
    public function beginThisyear(){
        return date("Y",time())."-1"."-1";
    }
    //本年结束时间
    public function endThisyear(){
        return date("Y",time())."-12"."-31";
    }
}
